#include "main.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "FreeRTOS.h"
#include "task.h"
#include "lcd.h"
#include "GBK_LibDrive.h"
#include "ad9833.h"
#include "ui.h"
#include "ec11.h"
#include "key.h"
#include "cpu.h"
#include "iwdg.h"
#include "max5400.h"

DATA_Display Display;

#define START_TASK_PRIO 1           
#define START_STK_SIZE 128          
TaskHandle_t StartTask_Handler;      
void start_task(void *pvParameters); 

#define LCD_TASK_PRIO 2      
#define LCD_STK_SIZE 512     
TaskHandle_t LCDTask_Handler; 
void LCD_Task(void *pvParameters);

#define KEY_SCAN_TASK_PRIO 3      
#define KEY_SCAN_STK_SIZE 64       
TaskHandle_t KEY_SCANTask_Handler;
void key_scan(void *pvParameters);

#define AD9833_TASK_PRIO 4
#define AD9833_STK_SIZE 128
TaskHandle_t AD9833Task_Handler;
void AD9833_stask(void *pvParameters);

#define CPU_RUN_TASK_PRIO 5      
#define CPU_RUN_STK_SIZE 512      
TaskHandle_t CPU_RUNTask_Handler; 
void cpu_run(void *pvParameters);

int main(void)
{
    delay_init(168);
    delay_ms(500);
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
    uart_init(9600);
    CPU_TIM_Init();
    EC11_Init();
    key_Init();
    LED_Init();
    AD9833_Init();
    LCD_Init();
    POINT_COLOR = RED;
    Display.Amplitude = 0;
    Display.Amplitude_1 = 0;
    Display.Freq = 100;
    Display.wave = Sine;
    Display.out_0 = 0;
    Display.out_1 = 1;
    Display.screen_light = 100;
    Display.CPU_usage = 0;
    Display.wave_speed = 1;
    AD9833.Amplitude = 0;
    AD9833.freq = 100.0;
    AD9833.wave_mode = Display.wave;
    AD9833.freq_d = 1.0;
    UI_start();
    LCD_Clear(LIGHTBLUE);
    UI_black();

    xTaskCreate((TaskFunction_t)start_task,
                (const char *)"start_task",
                (uint16_t)START_STK_SIZE,
                (void *)NULL,
                (UBaseType_t)START_TASK_PRIO,
                (TaskHandle_t *)&StartTask_Handler);
    vTaskStartScheduler();
}

void start_task(void *pvParameters)
{
    taskENTER_CRITICAL();

    delay_ms(10);

    xTaskCreate((TaskFunction_t)LCD_Task,
                (const char *)"LCD_Task",
                (uint16_t)LCD_STK_SIZE,
                (void *)NULL,
                (UBaseType_t)LCD_TASK_PRIO,
                (TaskHandle_t *)&LCDTask_Handler);

    delay_ms(10);

    xTaskCreate((TaskFunction_t)key_scan,
                (const char *)"key_scan",
                (uint16_t)KEY_SCAN_STK_SIZE,
                (void *)NULL,
                (UBaseType_t)KEY_SCAN_TASK_PRIO,
                (TaskHandle_t *)&KEY_SCANTask_Handler);

    delay_ms(10);

    xTaskCreate((TaskFunction_t)AD9833_stask,
                (const char *)"AD9833_stask",
                (uint16_t)AD9833_STK_SIZE,
                (void *)NULL,
                (UBaseType_t)AD9833_TASK_PRIO,
                (TaskHandle_t *)&AD9833Task_Handler);

    delay_ms(10);

    xTaskCreate((TaskFunction_t)cpu_run,
                (const char *)"cpu_run",
                (uint16_t)CPU_RUN_STK_SIZE,
                (void *)NULL,
                (UBaseType_t)CPU_RUN_TASK_PRIO,
                (TaskHandle_t *)&CPU_RUNTask_Handler);
    vTaskDelete(StartTask_Handler);

    taskEXIT_CRITICAL();
}

uint8_t cpu_data_process(uint8_t *Info)
{
    uint8_t result = 0;
    if (*Info == 0x00)
        return 0;
    while (*Info != 'I' || *(Info + 1) != 'D' && *(Info + 2) != 'L' && *(Info + 3) != 'E')
    {
        Info++;
    }
    while (*Info != 0x25)
        Info++;
    Info -= 3;
    while (*Info != 0x25)
    {
        if (*Info >= '0')
            result = result * 10 + (*Info - '0');
        Info++;
    }
    return result;
}

void cpu_run(void *pvParameters)
{
    uint8_t CPU_Info[512];
    while (1)
    {
        memset(CPU_Info, 0, 512);
        vTaskGetRunTimeStats((char *)&CPU_Info);
        Display.CPU_usage = 100 - cpu_data_process(CPU_Info);
        vTaskDelay(10);
    }
}
